package com.kandinfo.base.common.monitor;

import java.util.concurrent.ConcurrentHashMap;

import org.aopalliance.intercept.MethodInvocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.kandinfo.base.security.SecurityContext;

import net.bull.javamelody.MonitoringSpringInterceptor;


/**
* Class Name: MonitoringInterceptor
* Description: for performance monitoring purpose
* @author SC
*
*/
public class MonitoringInterceptor extends MonitoringSpringInterceptor {

    private static final long serialVersionUID = 1L;
    private static final Logger LOGGER = LoggerFactory.getLogger(MonitoringInterceptor.class);
    private static final long WARN_TIME = 2000L;
    private static final ConcurrentHashMap<String,Integer> map = new ConcurrentHashMap<String,Integer>();
    
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable { // NOSONAR
        long start = System.currentTimeMillis();
        try {
            return super.invoke(invocation);
        } finally {
            if(SecurityContext.getInstance().getCurrentUser()!=null){
                String key = invocation.getMethod().getDeclaringClass()
                        .getSimpleName()+"."+invocation.getMethod().getName()+"|"
                        +SecurityContext.getInstance().getCurrentUser().getName();
                if(map.containsKey(key)){
                    map.put(key, map.get(key)+1);
                }else{
                    map.put(key, 1);
                }
            }
   
            long time = System.currentTimeMillis() - start;
            
            if (time > WARN_TIME) {
                LOGGER.warn("[MON]{}.{}() completed in {}ms", invocation.getMethod().getDeclaringClass()
                        .getSimpleName(),
                        invocation.getMethod().getName(), time);
            } else {
                LOGGER.debug("[MON]{}.{}() completed in {}ms", invocation.getMethod().getDeclaringClass()
                        .getSimpleName(),
                        invocation.getMethod().getName(), time);
            }
        }

    }

}
